home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / drivers1.zip / EXPRESS.ASM < prev    next >
Assembly Source File  |  1992-01-23  |  53KB  |  1,828 lines

  1. version    equ    4
  2.  
  3.     include    defs.asm
  4.     include    8250defs.asm
  5. ;
  6. ;    Dave Price. October 30th 1990. 12:35.
  7. ;    Things much better now. I have had my standard
  8. ;    'FTP' test running at 2.5 Kbytes per second.
  9. ;    There is still a transmit bug though.. It appears
  10. ;    as the transmission of giant packets. I think I know
  11. ;    the source of the bug. I believe it occurs when we are
  12. ;    transmitting the last few bytes of a packet. Before
  13. ;    we change the interrupt mask to expect only TXDONE and
  14. ;    TXURUN, the TX fifo drains so that the TX419 condition
  15. ;    becomes true. The result is that the 8952 is already
  16. ;    waiting to interrupt us with the TX419. My code does not
  17. ;    expect anymore of these and acts incorrectly when
  18. ;    one arrives!
  19. ;
  20. ;    Dave Price. October 30th 1990 10:08.
  21. ;    After several minor changes the driver was almost
  22. ;    working. Some problems still existed however and
  23. ;    transferring data with FTP for instance
  24. ;    seemed to take a very long time. It appeared that
  25. ;    data was being lost, or that the routers or distant
  26. ;    host were so busy that packets were being dropped.
  27. ;    A further possible cause was that the timers used
  28. ;    by the TCP protocol engines were inappropriate or
  29. ;    in some sense incompatible. A carefull reading of
  30. ;    the data sheets implies that one can use the 'FIFO empty'
  31. ;    bits providing you make sure that at least 2 cycles
  32. ;    of a 2mHz clock occur after you read data and before you
  33. ;    read the interrupt flag register. This only amounts to
  34. ;    16 bus cycles on a 16Mhz PC. This is really very few
  35. ;    instructions. I have talked to Jeremy Bicknall at MITEL
  36. ;    and he seems to agree (I reported a potential design
  37. ;    bug with the 8952 generating false RX1519s - he will persue).
  38. ;    I have thus decided to use the RXBYTE bits to decide how
  39. ;    to process each item of data but use the RXFIFO empty state
  40. ;    to cease reading data.
  41. ;
  42. ;
  43. ;    Dave Price. October 24th 1990 11:10.
  44. ;    More changes again. The main idea now is 
  45. ;    to only have two states in the RX protocol engine.
  46. ;    It is either 'building' a frame or 'skipping'
  47. ;    to the next one. The actual interrupts will just
  48. ;    be used to indicate the point at which you should
  49. ;    stop processing the RXFIFO. There will be several
  50. ;    items to help. A minimum numbers of bytes to read,
  51. ;    a maximum number of bytes to read and a stop condition.
  52. ;    Processing the FIFO will cease when either the maximum
  53. ;    number of bytes have been processed, or BOTH the stop
  54. ;    condition and the minimum number have been processed.
  55. ;    On considering a new item of data a mask will be built
  56. ;    containing 5 bits that reflect a condition implied
  57. ;    by the data. Four bits are used to simply indicate
  58. ;    a packet byte, first byte, good last byte or bad last
  59. ;    byte. The fifth bit is used to indicate a frame abort
  60. ;    condition; this can only be determined by deciding
  61. ;    that the byte about to be read is a 'first' byte and
  62. ;    we already BUILDING a packet.
  63. ;    This change is a radical departure from previous
  64. ;    approaches to the RX code and might perhaps work
  65. ;    (HA, Ha!)
  66. ;
  67. ;    Dave Price. October 23rd 1990 16:06.
  68. ;    Some change of thought again.. I hate 8952s!
  69. ;    I am moving to four states in RX protocol engine.
  70. ;    'idle' will mean - finished one packet, awaiting next
  71. ;    'skipping' will mean we failed to get a buffer so
  72. ;    we are awaiting this packet to go by before trying
  73. ;    again for a buffer. I.E. we are discarding all input
  74. ;    waiting for an FA or EOPD etc etc
  75. ;    'found' means that the NEXT byte in the fifo
  76. ;    is a 'first' byte. I.E. here comes the packet...
  77. ;    'building' means we have a buffer and we are off
  78. ;    making up the next packet.
  79. ;
  80. ;    Dave Price. October 23rd 1990 09:40.
  81. ;    Having got completely fed up with lots of minor bugs
  82. ;    in the RX code, I am now carrying on with the changes
  83. ;    started earlier on 17th to attempt to have
  84. ;    some more clean code for the RX side. Most of the
  85. ;    code has been developed over the weekend but is 
  86. ;    handwriiten on the last listing. Problems
  87. ;    mainly arise with odd combinations of events
  88. ;    rather than simple circumstances. A major change is
  89. ;    that the RX code will now longer go and get itself
  90. ;    a buffer until the 'first byte' has been located. In
  91. ;    particular the completion of the collection of one
  92. ;    packet was immediately followed by the allocation
  93. ;    of a new buffer. This will now not happen.
  94. ;    I also intend at a later date to add fields to the
  95. ;    hdlc datastructure to hold port addresses etc. This
  96. ;    will start to pave the way for making the driver handle
  97. ;    multiple channels. It will require other changes as
  98. ;    well though (mainly stopping the code use constructions
  99. ;    like hdlc0.fred and instead move to set bx; [bx].fred.
  100. ;    This is not straightforward though as bs is already
  101. ;    used as a pointer. It will imply lots of pushing and
  102. ;    popping probably. All this is the next fix NOT
  103. ;    this change anyway.
  104. ;
  105. ;    October 17th 1990 20:30. Work starts to alter RX data
  106. ;    structures with a view to adding a 'state' variable
  107. ;    and dealing with input quite differently.
  108. ;
  109. ;    October 17th 1990.
  110. ;    Several new patches of code added to try to
  111. ;    the remaining bugs. Most bugs are caused by too long
  112. ;    packets being received (possibly because rx fails to
  113. ;    deal with FAs and RXOFLOWs correctly).
  114. ;
  115. ;    October 16th 1990. The code has now been used
  116. ;    fairly successfully. Some files have been transfered
  117. ;    using FTP from a sun via one NOS router over a 64Kbps
  118. ;    link from a second NOS PC. The central router had to
  119. ;    be rebooted once during the transfer as the driver
  120. ;    ran out of receive buffers! Amazingly the file
  121. ;    transfered o.k! The file was a 43Kbyte binary
  122. ;    of a virus checking program.
  123. ;    Code has been added to cope with RXofloe and Frame
  124. ;    abort, but bugs exist.
  125. ;
  126. ;    October 11th 1990.  The code has been running now
  127. ;    used by NOS. Some problems had occurred with 
  128. ;    events like txdone also having tx419 set.
  129. ;    Even though only txdone was enabled as an interrupt,
  130. ;    reading the 'interrupt flag register' showed both
  131. ;    bits set. As the code allows for several conditions
  132. ;    to be true it obeyed the one set of code and then 
  133. ;    attempted to handle the other condition too! This
  134. ;    resulted in errors.
  135. ;    The code now carefully processes txdone and then avoids
  136. ;    the tx419 condition!
  137. ;    Similar problems exist with eopd and fa!
  138. ;
  139. ;    October 1st 1990. Code is now in place to handle
  140. ;    rx and tx interrupts. user can also specify -n
  141. ;    so board acts as an NT.
  142. ;    Only RX1519, and EOPD handled on receive and TXDONE and
  143. ;    TX419 handles on transmit.
  144. ;
  145. ;    Buffer strategy Changed again. 25 September 1990. Dave Price
  146. ;    The idea now is that there will be a ring of
  147. ;    structures, each structure containing a little control
  148. ;     information plus a Data Unit in which will be placed
  149. ;    an IP frame (or potentially any other type of frame).
  150. ;    There will be two such rings, one for transmission
  151. ;    and one for reception.
  152. ;    The rings will be statically allocated.
  153. ;    The Data Units will be set at 1500 bytes, the same
  154. ;    as the maximum MTU for ethernet packet drivers.
  155. ;
  156. ;    Simple byte-ring-buffer has proved awkward to
  157. ;    code. One often seems to be fighting the INTEL CPU.
  158. ;    On reflection a 'frame' based approach might be better.
  159. ;
  160. ;    Added Code for RJG suggested Buffer Management. The
  161. ;    idea is described in an ARUW?? document. There will
  162. ;    be a circular ring buffer of bytes (like the slip
  163. ;    drivers) with an associated structure to hold the
  164. ;    state of the buffers.
  165. ;
  166. ;    More bits from Dave Price to initialize
  167. ;    MITEL express card. Just plugs voice so far.
  168. ;    30/8/90
  169. ;
  170. ; This is a hacked version of slip8250 packet driver.
  171. ; The hack is beginning on 28/8/90.
  172. ; First attempts are just to change messages etc!
  173. ;
  174. ;    Changes started by Dave Price
  175. ;
  176. ;Ported from Phil Karn's asy.c and slip.c, a C-language driver for the IBM-PC
  177. ;8250 by Russell Nelson.  Any bugs are due to Russell Nelson.
  178. ;16550 support ruthlessly stolen from Phil Karn's 8250.c. Bugs by Denis DeLaRoca
  179.  
  180. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  181.  
  182. ;   This program is free software; you can redistribute it and/or modify
  183. ;   it under the terms of the GNU General Public License as published by
  184. ;   the Free Software Foundation, version 1.
  185. ;
  186. ;   This program is distributed in the hope that it will be useful,
  187. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  188. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  189. ;   GNU General Public License for more details.
  190. ;
  191. ;   You should have received a copy of the GNU General Public License
  192. ;   along with this program; if not, write to the Free Software
  193. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  194.  
  195. code    segment    byte public
  196.     assume    cs:code, ds:code
  197. ;
  198. ;    Constants etc from MITEL Express card
  199. ;
  200. ;    First the DX (8980)
  201. ;
  202. board_w_dx    dw    0300h
  203.  
  204. dx_b_con        equ    0000h
  205. dx_b_cm_base    equ    0400h
  206.  
  207. dx_con_cmh        equ    00011000b
  208. dx_con_cml        equ    00010000b
  209. dx_cmh_mchan    equ    00000100b
  210. dx_cmh_oe        equ    00000001b
  211.  
  212. ;
  213. ;    Now the stream and channel assignments
  214. ;
  215. snic_stream        equ    6
  216. snic_d_channel    equ    0
  217. snic_c_channel    equ    1
  218. snic_b1_channel    equ    2
  219. snic_b2_channel    equ    3
  220.  
  221. hdlc_stream        equ    6
  222. hdlc_d_channel    equ    4
  223. hdlc_c_channel    equ    5
  224. hdlc_b1_channel    equ    6
  225. hdlc_b2_channel    equ    7
  226. hdlc_b3_channel    equ    8
  227.  
  228. dphone_stream        equ    7
  229. dphone_unused_channel    equ    4
  230. dphone_c_channel        equ    5
  231. dphone_b1_channel        equ    6
  232. dphone_b2_channel        equ    7
  233. dphone_b3_channel        equ    8
  234.  
  235. ;
  236. ;    Now some snic values etc
  237. ;
  238. board_w_snic        dw    0b00h
  239.  
  240. snic_b_master        equ    0000h
  241. snic_b_stbus        equ    0001h
  242.  
  243. snic_master_irqenable    equ    00000000b
  244. snic_master_msdisable    equ    00000010b
  245. snic_master_cstenable    equ    00000000b
  246.  
  247. snic_stbus_all    equ    0ffh
  248.  
  249. snic_c_ar        equ    10000000b
  250. snic_c_dr        equ    01000000b
  251. snic_c_dinb        equ    00100000b
  252. snic_c_priority    equ    00010000b
  253. snic_c_dreq        equ    00001000b
  254. snic_c_txmch    equ    00000100b
  255. snic_c_clrdia    equ    00000010b
  256. snic_c_regsel    equ    00000001b
  257.  
  258. ;
  259. ;    now some dphone values
  260. ;
  261. board_w_dphone    dw    1700h
  262.  
  263. dphone_b_c        equ    0000h
  264. dphone_b_time        equ    0005h
  265. dphone_b_wdog        equ    0006h
  266. dphone_b_tone1        equ    0007h
  267. dphone_b_tone2        equ    0008h
  268. dphone_b_dsp        equ    0009h
  269. dphone_b_trans        equ    000ah
  270. dphone_b_rgain        equ    000bh
  271. dphone_b_sddata    equ    000ch
  272. dphone_b_sddir        equ    000dh
  273. dphone_b_test        equ    000eh
  274.  
  275. dphone_sddir_allout    equ    0ffh
  276. dphone_sddata_te    equ    0b0h
  277. dphone_sddata_nt    equ    0b8h
  278.  
  279. dphone_time_pcmb1    equ    00000001b
  280. dphone_time_pcmb2    equ    00000100b
  281. dphone_time_pcmb3    equ    00010000b
  282.  
  283. dphone_time_c        equ    10000000b
  284.  
  285. dphone_tone_697        equ    59h
  286. dphone_tone_1209        equ    9bh
  287.  
  288. dphone_test_disable    equ    00h
  289.  
  290. dphone_dsp_cpcmen        equ    01000000b
  291. dphone_dsp_dpcmen        equ    00100000b
  292. dphone_dsp_dual        equ    00001000b
  293. dphone_dsp_tone        equ    00010000b
  294. dphone_dsp_speaker    equ    00011000b
  295. dphone_dsp_cadence    equ    00000100b
  296. dphone_dsp_warble16    equ    00000010b
  297. dphone_dsp_dspen        equ    00000001b
  298.  
  299. dphone_trans_dial        equ    00100000b
  300. dphone_trans_side        equ    00010000b
  301. dphone_trans_hsmic    equ    00001000b
  302. dphone_trans_spmic    equ    00000100b
  303. dphone_trans_spskr    equ    00000010b
  304. dphone_trans_hsskr    equ    00000001b
  305.  
  306. dphone_rgain_hpf        equ    10000000b
  307. dphone_rgain_rfg_m7    equ    01110000b
  308.  
  309. ;
  310. ;    now the hdlcs relative to the board base
  311. ;
  312. board_w_hdlc0    dw    0f00h
  313. board_w_hdlc1    dw    1300h
  314. ;
  315. ;    Now register offsets in the hdlc chips
  316. ;
  317. hdlc_br_fifostatus    equ    00h
  318. hdlc_br_receive        equ    01h
  319. hdlc_bw_transmit        equ    01h
  320. hdlc_b_control        equ    02h
  321. hdlc_b_raddress        equ    03h
  322. hdlc_b_cchancontrol    equ    04h
  323. hdlc_b_time            equ    05h
  324. hdlc_br_intflag        equ    06h
  325. hdlc_bw_wdog        equ    06h
  326. hdlc_bw_intenable        equ    07h
  327. hdlc_br_genstatus        equ    08h
  328. hdlc_br_cchanstatus    equ    09h
  329.  
  330. ;
  331. ;    Now some values for the registers of the hdlc's
  332. ;
  333. hdlc_fifostatus_RXBYTE        equ    11000000b
  334. hdlc_fifostatus_packet        equ    00000000b
  335. hdlc_fifostatus_first        equ    01000000b
  336. hdlc_fifostatus_good        equ    10000000b
  337. hdlc_fifostatus_bad        equ    01000000b
  338. hdlc_fifostatus_last        equ    10000000b
  339.  
  340. hdlc_fifostatus_RXFIFO        equ    00110000b
  341. hdlc_fifostatus_rxempty        equ    00000000b
  342. hdlc_fifostatus_rxle14        equ    00010000b
  343. hdlc_fifostatus_rxfull        equ    00100000b
  344. hdlc_fifostatus_rxge15        equ    00010000b
  345.  
  346. hdlc_fifostatus_TXFIFO        equ    00001100b
  347. hdlc_fifostatus_txfull        equ    00000000b
  348. hdlc_fifostatus_txge5        equ    00000100b
  349. hdlc_fifostatus_txempty        equ    00001000b
  350. hdlc_fifostatus_txle4         equ    00000100b
  351.  
  352. hdlc_control_txen        equ    10000000b
  353. hdlc_control_rxen        equ    01000000b
  354. hdlc_control_rxad        equ    00100000b
  355. hdlc_control_ra6        equ    00010000b
  356. hdlc_control_iftf1    equ    00001000b
  357. hdlc_control_iftf0    equ    00000100b
  358. hdlc_control_fa        equ    00000010b
  359. hdlc_control_eop        equ    00000001b
  360.  
  361. hdlc_control_idle        equ    00000000b
  362. hdlc_control_iftf        equ    00000100b
  363. hdlc_control_trans    equ    00001000b
  364. hdlc_control_goahead    equ    00001100b
  365.  
  366. hdlc_time_rst        equ    10000000b
  367. hdlc_time_ic        equ    01000000b
  368. hdlc_time_c1en        equ    00100000b
  369. hdlc_time_brck        equ    00010000b
  370. hdlc_time_tc        equ    00001111b
  371.  
  372. hdlc_time_c2bits8        equ    00000011b
  373. hdlc_time_c3bits8        equ    00000100b
  374. hdlc_time_c4bits8        equ    00000101b
  375. hdlc_time_c23bits16        equ    00000110b
  376. hdlc_time_c234bits24    equ    00000111b
  377.  
  378. hdlc_intflag_ga    equ    10000000b
  379. hdlc_intflag_eopd    equ    01000000b
  380. hdlc_intflag_txdone    equ    00100000b
  381. hdlc_intflag_fa    equ    00010000b
  382. hdlc_intflag_tx419    equ    00001000b
  383. hdlc_intflag_txurun    equ    00000100b
  384. hdlc_intflag_rx1519    equ    00000010b
  385. hdlc_intflag_rxoflw    equ    00000001b
  386.  
  387. hdlc_intenable_ga        equ    10000000b
  388. hdlc_intenable_eopd        equ    01000000b
  389. hdlc_intenable_txdone    equ    00100000b
  390. hdlc_intenable_fa        equ    00010000b
  391. hdlc_intenable_tx419    equ    00001000b
  392. hdlc_intenable_txurun    equ    00000100b
  393. hdlc_intenable_rx1519    equ    00000010b
  394. hdlc_intenable_rxoflw    equ    00000001b
  395.  
  396.  
  397. hdlc_genstatus_rxoflw    equ    10000000b
  398. hdlc_genstatus_txurun    equ    01000000b
  399. hdlc_genstatus_ga    equ    00100000b
  400. hdlc_genstatus_abrt    equ    00010000b
  401. hdlc_genstatus_irq    equ    00001000b
  402. hdlc_genstatus_idle    equ    00000100b
  403.  
  404.  
  405. ;
  406. ;    Now the overall interrupt register
  407. ;
  408. board_w_intreg    dw    1b00h
  409.  
  410. intreg_hdlc0    equ    00000010b    ;bit for hdlc0 interrupt
  411. intreg_hdlc1    equ    00000001b    ;bit for hdlc1 interrupt
  412. intreg_snic    equ    00000100b    ;bit for snic interrupt
  413. intreg_hphone    equ    00001000b    ;bit for d/hphone interrupt
  414. ;
  415. ;    now a few usefull macros
  416. ;
  417. out_chip_reg_value    macro    chip,reg,value
  418.     mov    dx,chip
  419.     add    dx,reg
  420.     mov    al,value
  421.     out    dx,al
  422.     endm
  423.  
  424. in_chip_reg        macro    chip,reg
  425.     mov    dx,chip
  426.     add    dx,reg
  427.     in    al,dx
  428.     endm
  429.  
  430. dx_message    macro    stream,channel,value
  431.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cmh or stream>
  432.  
  433.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or channel>,<dx_cmh_mchan or dx_cmh_oe>
  434.  
  435.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cml or stream>
  436.  
  437.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or channel>,value
  438.  
  439.     endm
  440.  
  441. dx_source    macro    d_stream,d_channel,s_stream,s_channel
  442.  
  443.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cmh or d_stream>
  444.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or d_channel>,dx_cmh_oe
  445.     out_chip_reg_value    board_w_dx,dx_b_con,<dx_con_cml or d_stream>
  446.     out_chip_reg_value    board_w_dx,<dx_b_cm_base or d_channel>,<s_stream shl 5 or s_channel>
  447.  
  448.     endm
  449.  
  450.     public    int_no
  451. int_no        db    7,0,0,0        ; interrupt number.
  452. NT_switch    db    0    ;if 0 be a TE else be an NT
  453.  
  454.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  455. driver_class    db    6,0,0,0        ;from the packet spec
  456. driver_type    db    0,0,0,0        ;from the packet spec
  457. driver_name    db    'EXPRESS',0    ;name of the driver.
  458. driver_function    db    2
  459. parameter_list    label    byte
  460.     db    1    ;major rev of packet driver
  461.     db    0    ;minor rev of packet driver
  462.     db    14    ;length of parameter list
  463.     db    EADDR_LEN    ;length of MAC-layer address
  464.     dw    GIANT    ;MTU, including MAC headers
  465.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  466.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  467.     dw    0    ;(# of successive xmits) - 1
  468.     dw    0    ;Interrupt # to hook for post-EOI
  469.             ;processing, 0 == none,
  470.  
  471. ;
  472. ;    Packet Buffer Structure
  473.  
  474. owner_k_empty    equ    0
  475. owner_k_queue    equ    1
  476. owner_k_isr    equ    2
  477. info_k_size    equ    1500    ;size of info area in buffer
  478. ;
  479. buff        struc
  480. buff_w_next    dw    0    ;pointer to next buffer
  481. buff_w_prev    dw    0    ;pointer to previous buffer
  482. buff_w_size    dw    0    ;size of frame in info area in bytes
  483. buff_w_owner    dw    owner_k_empty    ;current owner of buffer
  484. buff_info    db    info_k_size dup (0)    ;area for the Transfer Unit
  485. buff        ends
  486. ;
  487. ;    Structure for shared Queue Information
  488. ;    Now contains the info for the associated isr routines
  489. ;    as well. 17th October 1990.
  490. ;
  491. ;    First some constants.
  492. ;
  493. state_k_skipping    equ    00000001b
  494. state_k_building    equ    00000010b
  495. upcall_k_idle        equ    0
  496. upcall_k_active    equ    1
  497. ;
  498. hdlc_data        struc
  499. txq_w_front    dw    0    ;pointer to front of tx queue
  500. txq_w_back    dw    0    ;pointer to back of tx queue
  501. rxq_w_front    dw    0        ;pointer to front of rx queue
  502. rxq_w_back    dw    0        ;pointer to back of rx queue
  503. rxupcall_w_state    db    0    ;state of any upcall
  504. rxisr_w_state    db    0    ;the current state of the isr
  505. rxisr_w_pkt    dw    0    ;pointer to the packet being used by rx ISR
  506. rxisr_w_byte    dw    0    ;pointer to the byte the rx ISR will use next    
  507. rxisr_w_count    dw    0    ;count of bytes inserted so far
  508. txisr_w_pkt    dw    0    ;pointer to the packet being used by tx ISR
  509. txisr_w_byte    dw    0    ;pointer to the byte tx ISR will use next
  510. txisr_w_count    dw    0    ;count of bytes remaining
  511. copy_intflag    db    0    ;copy of latest value from int flag
  512. copy_intenable    db    0    ;copy of latest value sent int enable
  513. hdlc_data        ends
  514.  
  515. hdlc0_data    hdlc_data    <offset t1_buff, offset t1_buff, offset r1_buff, offset r1_buff,upcall_k_idle,state_k_skipping>            
  516.  
  517. ;
  518. ;    Names for the bits in the byte_status_mask
  519. ;    rint_status_mask
  520. ;    and the stop_status_mask
  521. ;
  522. mask_k_packet    equ    00000001b
  523. mask_k_first    equ    00000010b
  524. mask_k_good    equ    00000100b
  525. mask_k_bad        equ    00001000b
  526. mask_k_fabort    equ    00010000b
  527.  
  528. byte_status_mask    db    0    ;used to save status implied
  529.                     ;by the current bytes
  530. ;rint_status_mask    db    0    ;used to save status implied
  531.                     ;by the bytes so far in this
  532.                     ;segment in the fifo
  533. ;stop_status_mask    db    0    ;used to specify when we wish
  534.                     ;    to stop
  535. ;
  536. ;    Locations to hold counters of bytes read in
  537. ;    one particular call of the interrupt code.
  538. ;
  539.  
  540. ;number_read        db    0    ;number read so far
  541. ;minimum_read    db    0    ;minimum number that MUST be read
  542.                     ; the interrupt style sets this
  543. ;maximum_read    db    0    ;maximum available
  544.  
  545.     public    rcv_modes
  546. rcv_modes    dw    4        ;number    of receive modes in our table.
  547.         dw    0,0,0,rcv_mode_3
  548.  
  549.  
  550.     public    as_send_pkt
  551. ; The Asynchronous Transmit Packet routine.
  552. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  553. ;   interrupts possibly enabled.
  554. ; Exit with nc if ok, or else cy if error, dh set to error number.
  555. ;   es:di and interrupt enable flag preserved on exit.
  556. as_send_pkt:
  557.     ret
  558.  
  559.     public    drop_pkt
  560. ; Drop a packet from the queue.
  561. ; Enter with es:di -> iocb.
  562. drop_pkt:
  563.     assume    ds:nothing
  564.     ret
  565.  
  566.     public    xmit
  567. ; Process a transmit interrupt with the least possible latency to achieve
  568. ;   back-to-back packet transmissions.
  569. ; May only use ax and dx.
  570. xmit:
  571.     assume    ds:nothing
  572.     ret
  573.  
  574.  
  575.     public    send_pkt
  576. ;
  577.  
  578. send_pkt:
  579. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  580. ;  (only if the high-performance bit is set in driver_function)
  581. ;enter with ds:si -> packet, cx = packet length.
  582. ;exit with nc if ok, or else cy if error, dh set to error number.
  583. ;called from telnet layer via software interrupt
  584.     assume    ds:nothing
  585.  
  586.     push    cs
  587.     pop    es
  588.     assume    es:code
  589.     sti                ; enable interrupts
  590. ;
  591. ;    NOTE Using ES as segment for data accesses
  592. ;
  593.     mov    bx,es:hdlc0_data.txq_w_back    ;get pointer to back of queue
  594.     cmp    es:[bx].buff_w_owner,owner_k_empty    ;is it empty?
  595.     jne    no_buffers_left        ;no so error return...
  596.  
  597.     cmp    cx,info_k_size        ;    check packet size o.k.
  598.     jle    send_pkt_size_ok    ; its fine
  599.     pr_ch_al    'a'            ;    error trace message
  600.     mov    dh,CANT_SEND    ;return an error code
  601.     cli
  602.     stc
  603.     ret
  604.  
  605. send_pkt_size_ok:
  606.     mov    es:[bx].buff_w_size,cx    ;save size
  607.     lea    di,es:[bx].buff_info        ;
  608.     rep    movsb                ;and copy the packet
  609.  
  610.     mov    es:[bx].buff_w_owner,owner_k_queue     ;give it to queue
  611.     mov    bx,es:[bx].buff_w_next    ;point to buffer
  612.     mov    es:hdlc0_data.txq_w_back,bx        ;adjust back of the queue
  613. ;
  614. ;    NOW WE NEED TO PROVOKE LOADING OF TXFIFO
  615. ;    IF WE THINK ISR GONE QUIET
  616. ;
  617. ; structure is at zero no ints active
  618.     cli        ;block interrupts starting before we exit
  619.     cmp    es:hdlc0_data.txisr_w_pkt,0
  620.     je    send_pkt_int_quiet    ; jump if interrupts quiet
  621.     clc                    ;clear carry because all o.k.
  622.     ret
  623. ;
  624. ;    Else we now need to kick the interrupt code
  625. ;
  626. send_pkt_int_quiet:
  627.     push    ds        ;save old ds and make it point to code
  628.     push    cs
  629.     pop    ds
  630.     pr_ch_al    'b'
  631.     call    tint_new        ;manually call the tint routine !
  632.     pop    ds            ;restore old ds and
  633.     ret                ;return
  634.  
  635.  
  636. no_buffers_left:
  637.     pr_ch_al    'c'
  638.     mov    dh,NO_SPACE
  639.     cli    ;block interrupts before we exit
  640.     stc            ;signal its an error - no more buffers
  641.     ret
  642.  
  643.     public    get_address
  644. get_address:
  645. ;get the address of the interface.
  646. ;enter with es:di -> place to get the address, cx = size of address buffer.
  647. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  648.     assume    ds:code
  649.     mov    cx,0
  650.     clc
  651.     ret
  652.  
  653.  
  654.     public    set_address
  655. set_address:
  656. ;set the address of the interface.
  657. ;enter with es:di -> place to get the address, cx = size of address buffer.
  658. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  659.     assume    ds:nothing
  660.     clc
  661.     ret
  662.  
  663.  
  664. rcv_mode_3:
  665. ;receive mode 3 is the only one we support, so we don't have to do anything.
  666.     ret
  667.  
  668.  
  669.     public    set_multicast_list
  670. set_multicast_list:
  671. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  672. ;return nc if we set all of them, or cy,dh=error if we didn't.
  673.     mov    dh,NO_MULTICAST
  674.     stc
  675.     ret
  676.  
  677.  
  678.     public    get_multicast_list
  679. get_multicast_list:
  680. ;return with nc, es:di ->list of multicast addresses, cx = number of bytes.
  681. ;return    cy, NO_ERROR if we don't remember all of the addresses ourselves.
  682. ;return cy, NO_MULTICAST if we don't implement multicast.
  683.     mov    dh,NO_MULTICAST
  684.     stc
  685.     ret
  686.  
  687.  
  688.     public    terminate
  689. terminate:
  690.     ret
  691.  
  692.     public    reset_interface
  693. reset_interface:
  694. ;reset the interface.
  695.     assume    ds:code
  696.     ret
  697.  
  698.  
  699. ;called    when we    want to determine what to do with a received packet.
  700. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  701.     extrn    recv_find: near
  702.  
  703. ;called after we have copied the packet into the buffer.
  704. ;enter with ds:si ->the packet, cx = length of the packet.
  705.     extrn    recv_copy: near
  706.  
  707.     extrn    count_in_err: near
  708.     extrn    count_out_err: near
  709.     
  710.     public    recv
  711.  
  712. recv:
  713. ;called from the recv isr.  All registers have been saved, and ds=cs.
  714. ;Upon exit, the interrupt will be acknowledged.
  715.     assume    ds:code
  716. recv_2:
  717.     in_chip_reg        board_w_intreg,0    ; get interrupt source
  718.  
  719.     test    al,intreg_hdlc0        ;check if HDLC0
  720.     jne    not_hdlc0
  721.  
  722.     jmp    which_reg        ;Jump and check the chip
  723.  
  724. not_hdlc0:
  725.     pr_ch_al    '+'
  726.     ret            ;Not this chip so give up
  727.  
  728. which_reg:
  729.     in_chip_reg        board_w_hdlc0,hdlc_br_intflag
  730.     mov    hdlc0_data.copy_intflag,al    ;save the interrupt flags
  731. ;
  732. ;    We now analyse for the different interrupts that
  733. ;    may be present. We first make some tests for styles
  734. ;    of interrupts so we dont need to check everything
  735. ;    each time.
  736. ;
  737.     test    hdlc0_data.copy_intflag,hdlc_intflag_eopd or hdlc_intflag_fa or hdlc_intflag_rx1519 or hdlc_intflag_rxoflw
  738.     je    test_tint    ;No receive style interrupts so jump
  739.  
  740. ; There is a receive event
  741. ;
  742. ;    We recognise 8 receive events.
  743. ;    1/.    RX1519
  744. ;    2/.    RX1519 + RXOFLW
  745. ;    3/.    EOPD
  746. ;    4/.    EOPD+RX1519
  747. ;    5/.    EOPD + RX1519 + RXOFLW
  748. ;    6/.    FA + EOPD
  749. ;    7/.    FA + EOPD + RX1519
  750. ;    8/.    FA + EOPD + RX1519 + RXOFLW
  751. ;    We believe that other (potential) RX events cannot
  752. ;    occur. 
  753. ;    We recognise only three (major) states for the RX
  754. ;    protocol engine.
  755. ;    1/.    SKIPPING for the start of a packet; all data
  756. ;        is essentially ignored in this state. No
  757. ;        receive buffer will have been allocated.
  758. ;        We are in this state between packets or perhaps
  759. ;        because we have just run out of buffers!
  760. ;        See also state 3 below.
  761. ;    2/.    BUILDING a packet. Generally speaking,
  762. ;        providing we have enough room, 'packet' bytes
  763. ;        are just added into the buffer, 'good last' bytes
  764. ;        terminating the building of a packet and provoke
  765. ;        its delivery to the upper layer. Other data such
  766. ;        as 'bad last' or 'first' bytes cause the packet
  767. ;        being built to be discarded and the engine to
  768. ;        move to SKIPPING state. A first byte implies
  769. ;        a frame abort has been received of course.
  770. ;    3/.    It is also possible to be SKIPPING&BUILDING !
  771. ;        This occurs after we have read data that
  772. ;        would have moved us to BUILDING state but
  773. ;        we could not get buffer space. We need this
  774. ;        to properly detect frame aborts (see below).
  775. ;
  776. ;    EVENT PROCESSING in a little more detail.
  777. ;
  778. ;    1/. RX1519
  779. ;    We are required to clear 14 bytes from the fifo.
  780. ;    It is possible to show that in pathological
  781. ;    circumstances bytes other than packet bytes can
  782. ;    be in the FIFO!
  783. ;
  784. ;    2/.    RX1519 + RXOFLW
  785. ;    Regardless of state, we read 19 bytes from the FIFO.
  786. ;    We do this as we do not want to accidently
  787. ;    discard the front of a following packet.
  788. ;
  789. ;    3/.    EOPD
  790. ;    We process bytes up to a bad/good last byte.
  791. ;    We then deliver or discard the packet.
  792. ;    Clearly should not process more than 19 and
  793. ;    if RX1519 set it would be surprising if we
  794. ;    processed more than 14!
  795. ;
  796. ;    4/.    EOPD + RX1519
  797. ;    We are required to clear 14 bytes from the fifo.
  798. ;    Process as in 3/. above but make sure we clear
  799. ;    at LEAST 14 bytes. We might read more than 15
  800. ;    if for instance the EOPD occurred as the 16 byte
  801. ;    which had arrived while we were responding to
  802. ;    the event which interrupted us which was a 'packet'
  803. ;    byte in number 15. It is also possible that the 'last'
  804. ;    byte might be number 14 but a 'first' byte also arrived
  805. ;    in 15 creating the RX1519 to occur as well.
  806. ;
  807. ;    5/.    EOPD + RX1519 + RXOFLW
  808. ;    The RXOFLW implies we have missed stuff and some
  809. ;    data failed to get into the end of the FIFO. The
  810. ;    RX FIFO is supposed to enter a FLAG search mode after
  811. ;    overflowing. Thus is we process as in 3/. but EMPTY
  812. ;    the whole buffer(i.e. read 19 bytes)., 
  813. ;
  814. ;    6,7,8/.    I.E. any FA condition.
  815. ;    We will read upto 19 bytes of data. It would
  816. ;    be surprising if we read more than 14 unless RX1519
  817. ;    was also set. We will end when we discover a Frame
  818. ;    Abort condition. This is implied by a first byte
  819. ;    when building but ALSO by a first byte if skipping
  820. ;    and we have already seen a first byte!
  821. ;
  822. ;
  823. ;    Now set up some values. The maximum and minimum
  824. ;    count values, the current number read
  825. ;    and we clear the stop_status_mask.
  826.  
  827. ;    mov    minimum_read,1    ;often increased below
  828. ;    mov    maximum_read,14    ;typically we end before this
  829. ;    mov    stop_status_mask,0    ;clear the stop status mask
  830. ;
  831. ;test_fa:
  832. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_fa
  833. ;    je    test_eopd
  834.     ; We have an FA so change stop_status_mask
  835.     ; and change the maximum read to 19 (?)
  836. ;    mov    stop_status_mask,mask_k_fabort
  837. ;    mov    maximum_read,19    ;typically we end before this
  838. ;    jmp    test_rxoflw    ;can avoid the eopd check
  839. ;
  840. ;test_eopd:
  841. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_eopd
  842. ;    je    test_rxoflw
  843. ;    ; Its eopd so update stop_status_mask
  844. ;    ; and change the maximum read to 19 (?)
  845. ;    mov    stop_status_mask,mask_k_good or mask_k_bad
  846. ;    mov    maximum_read,19    ;typically we end before this
  847. ;
  848. ;test_rxoflw:
  849. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_rxoflw
  850. ;    je    test_rx1519
  851. ;    ; Its Overflow so adjust minimum read number
  852. ;    ; and change the maximum read to 19 (?)
  853. ;    mov    minimum_read,19
  854. ;    mov    maximum_read,19    ;typically we end before this
  855. ;    jmp    test_rx_end    ;can avoid the rx1519 check
  856. ;
  857. ;test_rx1519:
  858. ;    test    hdlc0_data.copy_intflag,hdlc_intflag_rx1519
  859. ;    je    test_rx_end
  860. ;    ; Its Rx1519 so adjust the minimum read number
  861. ;    mov    minimum_read,14
  862. ;
  863. test_rx_end:
  864. ;
  865. ;WE DONT CARE WHAT CAUSED THE INTERRUPT NOW!
  866. ;
  867.     ; Now we call the routine to process the RX fifo having
  868.     ; hopefully set up all the correct conditions.
  869.  
  870.     call    rint_process
  871.  
  872. test_tint:
  873.     mov    al,hdlc0_data.copy_intflag
  874.     and    al,hdlc0_data.copy_intenable ; ignore any not expected
  875.     mov    hdlc0_data.copy_intflag,al
  876.  
  877.     test    hdlc0_data.copy_intflag,hdlc_intflag_txdone or hdlc_intflag_tx419 or hdlc_intflag_txurun
  878.     je    test_ga    ;No transmit style interrupts so jump
  879.  
  880. ; Its some sort of transmit event
  881.  
  882.     test    hdlc0_data.copy_intflag,hdlc_intflag_txurun
  883.     je    test_txdone
  884.     call    tint_txurun; its an underrun event
  885. ;    Now need to avoid the txdone and tx419 code etc ....
  886.     jmp    test_ga
  887.  
  888. test_txdone:
  889.     test    hdlc0_data.copy_intflag,hdlc_intflag_txdone
  890.     je    test_tx419
  891.     call    tint_txdone; its packet trans. complete event
  892.     jmp test_ga            ; NOTE tx419 will always be set
  893.         ;when txdone is set! As we have processed
  894.         ;the outgoing packet we must now NOT go
  895.         ;through the tx419 code as well! IMPORTANT!
  896.  
  897. test_tx419:
  898.     test    hdlc0_data.copy_intflag,hdlc_intflag_tx419
  899.     je    test_ga
  900.     call    tint_tx419; its a tx fifo low event
  901.  
  902. ; and carry on...
  903.  
  904. test_ga:
  905.     test    hdlc0_data.copy_intflag,hdlc_intflag_ga
  906.     je    int_fin
  907.  
  908. ;    Its a Go-ahead .. We should not get these..
  909.  
  910.     pr_ch_al    '-'
  911.  
  912. int_fin:
  913.  
  914. ;    Now we have finished.. Just output H so we can check
  915.  
  916.     ret
  917.  
  918. ;
  919. ;Process 8952 Receive interrupts
  920. ;
  921.  
  922. ;    Process all RX FIFO data
  923.  
  924. rint_process:    
  925. ;    pr_ch_al    'A'
  926.  
  927. ;    mov    number_read,0    ;none so far...
  928. ;    mov    rint_status_mask,0    ;clear the rint status mask
  929.  
  930.     push    ds            ; get set up for the routine
  931.     pop    es
  932.  
  933. rint_loop:
  934. ;    NEED FIXES IN HERE
  935. ;    mov    al,number_read
  936. ;    cmp    maximum_read,al    ;check if data still due
  937. ;    jg    rint_some_due    ;yes there is
  938. ;    pr_ch_al    'B'
  939. ;    ret                ;no we have finished
  940.  
  941. ;rint_some_due:
  942.  
  943.     ;get fifo status and build into a mask
  944.     ;must first check that there is still some data left..
  945.     ; NOTE it is important that we dont get here less than
  946.     ; one microsecond after we last removed data.
  947.  
  948.     in_chip_reg        board_w_hdlc0,hdlc_br_fifostatus
  949.     test    al,hdlc_fifostatus_RXFIFO
  950.     jne    rint_fifo_not_empty
  951.     ret                    ; we have now emptied the RX FIFO
  952.                         ; so we return...
  953. rint_fifo_not_empty:        ;still some data so analyze...
  954.     mov    cl,6        ;number of bits to shift
  955.     and    al,hdlc_fifostatus_RXBYTE ;get RX byte status
  956.     shr    al,cl        ;shift to lower two bits
  957.     mov    cl,al        ;transfer to cl
  958.     mov    al,00000001b    ;set low bit in al
  959.     shl    al,cl            ;and shift to correct bit for mask
  960.     mov    byte_status_mask,al    ;save byte status mask
  961. ;    or    rint_status_mask,al    ;save rint segment status mask
  962.  
  963. ;
  964. ;    Now check our state
  965. ;
  966.     test    hdlc0_data.rxisr_w_state,state_k_skipping
  967.     jz    rint_building    ;must be building alone
  968.     jmp    rint_skipping    ;skipping or skipping&building
  969.  
  970. ;
  971. ;    Definitely building a packet
  972. ;
  973. rint_building:
  974.  
  975.     test    byte_status_mask,mask_k_good;good last byte ?        
  976.     jnz    rint_build_good_last            ;deal with good last byte
  977.  
  978.     test    byte_status_mask,mask_k_bad;bad last byte ?        
  979.     jnz    rint_build_bad_last            ;deal with bad last byte
  980.  
  981.     test    byte_status_mask,mask_k_first;first byte ?        
  982.     jnz    rint_build_first            ;deal with first byte
  983.  
  984. ;
  985. ;    must be packet byte
  986. ;
  987.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  988.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  989.     stosb            ;store char into buffer
  990.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  991.     
  992.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  993. ;    inc    number_read            ;count for this isr
  994.  
  995.     jmp    rint_end
  996.  
  997. rint_build_good_last:
  998. ;
  999. ;    good last byte coming, get it, then close
  1000. ;    the packet and assign it to queue ownership etc.
  1001. ;    then bump the pointers
  1002. ;
  1003. ;    pr_ch_al    'C'
  1004.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1005.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  1006.     stosb            ;store char into buffer
  1007.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  1008.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  1009. ;    inc    number_read            ;count for this isr
  1010.  
  1011.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get pointer to buffer
  1012.  
  1013.     mov    ax,hdlc0_data.rxisr_w_count ;save count in buffer
  1014.  
  1015.     mov    [bx].buff_w_size,ax ;via ax
  1016.  
  1017.     mov    [bx].buff_w_owner,owner_k_queue    ;mark in q
  1018.     mov    bx,[bx].buff_w_next    ;get pointer to next
  1019.     mov    hdlc0_data.rxq_w_back,bx    ;and save as back of queue
  1020. ;
  1021. ;    and change state
  1022. ;
  1023.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1024.  
  1025.     jmp    rint_end
  1026.  
  1027. rint_build_bad_last:
  1028.  
  1029. ;
  1030. ;    Now deal with bad FCS, read the bad byte and then
  1031. ;    then discard the packet we have got so far.
  1032. ;
  1033.     pr_ch_al    'D'
  1034.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1035.                 ;get char but ignore
  1036. ;    inc    number_read            ;count for this isr
  1037.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1038.     call    rint_reset    ;release the buffer etc
  1039. ;
  1040. ;    and change state
  1041. ;
  1042.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1043.     jmp rint_end
  1044.  
  1045. rint_build_first:
  1046. ;
  1047. ;    Now deal with first byte, this must be a frame abort!
  1048. ;    DONT read the byte, leave it there for next iteration
  1049. ;    to use as part of the next packet.
  1050. ;    Discard the packet we have got so far.
  1051. ;
  1052.     pr_ch_al    'E'
  1053.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1054.     call    rint_reset    ;release the buffer etc
  1055. ;
  1056. ;    Record the Frame Abort in the rint_status_mask
  1057. ;
  1058. ;    or    rint_status_mask,mask_k_fabort
  1059. ;
  1060. ;    and change state
  1061. ;
  1062.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1063.     jmp rint_end
  1064.  
  1065. rint_skipping:
  1066. ;
  1067. ;    If we are here then we must be in between packets.
  1068. ;    It is possible that we may have run out of buffers
  1069. ;    so we may be actually discarding data that would
  1070. ;    otherwise have been good. If this second situation
  1071. ;    exists then both the building and skipping bits
  1072. ;    are set in the state mask.
  1073. ;
  1074.  
  1075.     test    byte_status_mask,mask_k_good;good last byte ?        
  1076.     jnz    rint_skip_good_last            ;deal with good last byte
  1077.  
  1078.     test    byte_status_mask,mask_k_bad;bad last byte ?        
  1079.     jnz    rint_skip_bad_last            ;deal with bad last byte
  1080.  
  1081.     test    byte_status_mask,mask_k_first;first byte ?        
  1082.     jnz    rint_skip_first            ;deal with first byte
  1083.  
  1084. ;
  1085. ;    must be packet byte
  1086. ;
  1087.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1088.                 ;get char but ignore
  1089. ;    inc    number_read            ;count for this isr
  1090. ;
  1091. ;    Well we are certainly skipping past bytes now.
  1092. ;
  1093.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1094.  
  1095.     jmp    rint_end
  1096.  
  1097. rint_skip_good_last:
  1098. ;
  1099. ;    good last byte coming, get it, and ignore
  1100. ;
  1101.     pr_ch_al    'F'
  1102.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1103.                 ;get char but ignore
  1104. ;    inc    number_read            ;count for this isr
  1105.  
  1106. ;
  1107. ;    change state (might have been skipping and building)
  1108. ;
  1109.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1110.  
  1111.     jmp    rint_end
  1112.  
  1113. rint_skip_bad_last:
  1114.  
  1115. ;
  1116. ;    Now deal with bad FCS, read the bad byte and ignore
  1117. ;
  1118.     pr_ch_al    'G'
  1119.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1120.                 ;get char but ignore
  1121. ;    inc    number_read            ;count for this isr
  1122. ;
  1123. ;    change state (might have been skipping and building)
  1124. ;
  1125.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1126.     jmp rint_end
  1127.  
  1128. rint_skip_first:
  1129.  
  1130. ;
  1131. ;    Now deal with first byte, this must be the start
  1132. ;    of the next packet.
  1133. ;
  1134.     test    hdlc0_data.rxisr_w_state,state_k_building
  1135.     jnz    rint_skip_build    ;skipping&building
  1136. ;
  1137. ;    As we are here we are just skipping at the moment.
  1138. ;    As we have found a first byte, we now try to
  1139. ;    get a buffer in which to build the new packet.
  1140. ;
  1141.     call    rint_get_buffer
  1142.     jnc    rint_skip_first_got_buffer
  1143. ;
  1144. ;    We failed to get buffer. We thus must discard
  1145. ;    the incoming data, count it and move to the
  1146. ;    skipping&building state.
  1147. ;
  1148.     pr_ch_al    'H'
  1149.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1150.                 ;get char but ignore
  1151. ;    inc    number_read            ;count for this isr
  1152. ;
  1153. ;    and change state
  1154. ;
  1155.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1156.     jmp rint_end
  1157.  
  1158. rint_skip_first_got_buffer:
  1159. ;    pr_ch_al    'I'
  1160.     in_chip_reg        board_w_hdlc0,hdlc_br_receive
  1161.     mov    di,hdlc0_data.rxisr_w_byte ;get ptr to next byte
  1162.     stosb            ;store char into buffer
  1163.     mov    hdlc0_data.rxisr_w_byte,di ;save ptr to next byte
  1164.     
  1165.     inc    hdlc0_data.rxisr_w_count            ;count for all isr calls
  1166. ;    inc    number_read            ;count for this isr
  1167. ;
  1168. ;    and change state
  1169. ;
  1170.     mov    hdlc0_data.rxisr_w_state,state_k_building
  1171.     jmp    rint_end
  1172.  
  1173. rint_skip_build:
  1174. ;
  1175. ;    We are skipping and building. I.e. we are
  1176. ;    discarding data that probably would have been
  1177. ;    good but we had no buffers available.
  1178. ;    Thus if we find a first byte this must be a frame
  1179. ;    abort. Deal with it as such, leaving the byte in
  1180. ;    the FIFO to be picked up on the next cycle.
  1181. ;
  1182. ;    Record the Frame Abort in the rint_status_mask
  1183. ;
  1184.     pr_ch_al    'J'
  1185. ;    or    rint_status_mask,mask_k_fabort
  1186. ;
  1187. ;    and change state
  1188. ;
  1189.     mov    hdlc0_data.rxisr_w_state,state_k_skipping
  1190.  
  1191.     jmp rint_end
  1192.  
  1193. rint_end:
  1194. ;
  1195. ;    Now is the time to tidy up at the end of
  1196. ;    the rint loop. Several things to check. For instance,
  1197. ;    if we are still building and not skipping then
  1198. ;    if the packet is already full we have a problem.
  1199. ;    The best policy must be to discard and move
  1200. ;    to skipping&building state.
  1201. ;
  1202. ;    We must also check if we need to stop iterating.
  1203. ;    If we have not yet read the minimum_read number
  1204. ;    of bytes we must go again. If we have, then
  1205. ;    unless we have got a rint_status_mask that has 
  1206. ;    at least one bit in common with our stop_status_mask
  1207. ;    we must also loop again.
  1208.  
  1209.     test    hdlc0_data.rxisr_w_state,state_k_skipping
  1210.     jnz    rint_info_size_ok    ;dont care...
  1211.  
  1212.     cmp    hdlc0_data.rxisr_w_count,info_k_size    ;check if room for more info
  1213.     jl    rint_info_size_ok    ;and branch if ok
  1214. ;
  1215. ;    TOO much data in this packet, the next byte
  1216. ;    even if it were a last byte would overfill
  1217. ;    the info area. We must therefore discard the packet
  1218. ;    and move to the skipping&building state.
  1219.     pr_ch_al    'K'
  1220.     mov    bx,hdlc0_data.rxisr_w_pkt    ;get ptr to buffer
  1221.     call    rint_reset    ;release the buffer etc
  1222. ;
  1223. ;    and change state
  1224. ;
  1225.     mov    hdlc0_data.rxisr_w_state,state_k_skipping or state_k_building
  1226.  
  1227. rint_info_size_ok:
  1228. ;    mov    al,number_read
  1229. ;    cmp    minimum_read,al    ;have we read enough?
  1230. ;    jle    rint_enough            ;yes
  1231.     jmp    rint_loop                ; no go read some more..
  1232.  
  1233. ;rint_enough:
  1234. ;    mov    al,stop_status_mask
  1235. ;    test    rint_status_mask,al    ;stop state?
  1236. ;    jnz    rint_stop_state        ;yes
  1237. ;    jmp    rint_loop                ; no go read some more..
  1238.  
  1239. ;rint_stop_state:
  1240. ;
  1241. ;    Well that seems to be it for this call to the RX
  1242. ;    interrupt service routine so bye bye...
  1243.  
  1244. ;    ret
  1245.     
  1246. ;
  1247. ;    Routine to get a buffer (or not)
  1248. ;
  1249.  
  1250. rint_get_buffer:
  1251. ;    pr_ch_al    'L'
  1252.  
  1253.     mov    bx,hdlc0_data.rxq_w_back    ;get back of queue
  1254.     cmp    [bx].buff_w_owner,owner_k_empty    ;is it empty?
  1255.     jne    cant_get_buffer
  1256.  
  1257.     call rint_grab
  1258.     clc        ;all o.k.
  1259.     ret
  1260. cant_get_buffer:
  1261.     pr_ch_al    'M'
  1262.     stc        ;signal error (well at least no buffers left)
  1263.     ret
  1264.  
  1265. rint_grab:
  1266.     or    bx,bx
  1267.     jz    rint_grab_problem
  1268.     mov    [bx].buff_w_owner,owner_k_isr    ;mark inuse by isr
  1269.     mov    hdlc0_data.rxisr_w_pkt,bx    ;save for isr to use next
  1270.     lea    ax,[bx].buff_info    ;get address of new info area
  1271.     mov    hdlc0_data.rxisr_w_byte,ax    ;save for isr
  1272.     mov    hdlc0_data.rxisr_w_count,0    ;and clear count
  1273. ;    Now set the state to mark as BUILDING
  1274.     mov    hdlc0_data.rxisr_w_state,state_k_building
  1275.     clc
  1276.     ret
  1277. rint_grab_problem:
  1278.     pr_ch_al    'N'
  1279.     stc
  1280.     ret
  1281.  
  1282. rint_reset:
  1283.     or    bx,bx
  1284.     jz    rint_reset_problem
  1285.     mov    [bx].buff_w_owner,owner_k_empty    ;mark empty
  1286.     clc
  1287.     ret
  1288. rint_reset_problem:
  1289.     pr_ch_al    'O'
  1290.     stc
  1291.     ret
  1292.  
  1293. ; --------------------------------------------------------------
  1294. ;
  1295. ;  recv_exiting
  1296. ;
  1297.     public    recv_exiting
  1298. recv_exiting:
  1299.     push    ax
  1300.     push    bx
  1301.     mov    bx,hdlc0_data.rxq_w_front        ;get pointer to next buffer
  1302.     cmp    [bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1303.     jne    recv_exiting_exit           ; no - skip to end
  1304.     push    cx
  1305.     push    dx
  1306.     push    ds
  1307.     push    es
  1308.     push    bp
  1309.     push    di
  1310.     push    si
  1311.     push    cs            ; point ds properly
  1312.     pop    ds
  1313.     cmp    hdlc0_data.rxupcall_w_state,upcall_k_idle    ;is receive frame already active?
  1314.     jne    already_active        ;frame will be caught so jump
  1315.     mov    hdlc0_data.rxupcall_w_state,upcall_k_active    ;else mark recv_frame starting
  1316.     sti                ; enable interrupts
  1317.  
  1318.     call    recv_frame
  1319.  
  1320.     cli
  1321. already_active:
  1322.     pop    si
  1323.     pop    di
  1324.     pop    bp
  1325.     pop    es
  1326.     pop    ds
  1327.     pop    dx
  1328.     pop    cx
  1329. recv_exiting_exit:
  1330.     pop    bx
  1331.     pop    ax
  1332.     ret
  1333.  
  1334.  
  1335. ; --------------------------------------------------------------
  1336. ;
  1337. ;  recv_frame
  1338. ;
  1339.   ifdef debug
  1340.     public recv_frame
  1341.   endif
  1342. recv_frame:
  1343. ;    pr_ch_al    'P'
  1344.  
  1345.     mov    bx,hdlc0_data.rxq_w_front        ;get pointer to next buffer
  1346.  
  1347. recv_frame_2:
  1348.     lea    si,[bx].buff_info        ;point to data
  1349.     mov    cx,[bx].buff_w_size    ;get its size
  1350.     jcxz    recv_frame_3        ;count zero? yes,just free frame.
  1351. ;we don't need to set the type because none are defined for our HDLC encoding.
  1352.     push    si            ;save si in case we reject it.
  1353.     push    bx
  1354.     mov    di,0            ;but we avoid any segment end bullshit.
  1355.     mov    dl,cs:driver_class
  1356.     call    recv_find        ;look up our type.
  1357.     pop    bx
  1358.     pop    si
  1359.  
  1360.     mov    ax,es            ;is this pointer null?
  1361.     or    ax,di
  1362.     je    recv_frame_3        ;yes - just free the frame.
  1363. ;    pr_ch_al    'Q'
  1364.     push    cx
  1365.     push    es            ;remember where the buffer pointer is.
  1366.     push    di
  1367.  
  1368.     rep    movsb    ;and copy our packet into users buffer
  1369.  
  1370.     pop    si            ;now give the frame to the client.
  1371.     pop    ds
  1372.     pop    cx
  1373. ;    pr_ch_al    'R'
  1374.     assume    ds:nothing
  1375.  
  1376.     call    recv_copy
  1377.     push    cs
  1378.     pop    ds
  1379.     pr_ch_al    'S'
  1380.     assume    ds:code
  1381.  
  1382. recv_frame_3:
  1383.     mov    [bx].buff_w_owner,owner_k_empty    ;free the buffer
  1384.     mov    bx,[bx].buff_w_next        ;get pointer to next
  1385.     mov    hdlc0_data.rxq_w_front,bx        ;adjust front of q
  1386.  
  1387.     cmp    [bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1388.     je    recv_frame_2        ; yes so process this one.
  1389.     mov    hdlc0_data.rxupcall_w_state,upcall_k_idle    ;else mark recv_frame as inactive
  1390. ;    pr_ch_al    'T'
  1391.     ret
  1392.  
  1393. ;Handle 8952 transmitter interrupts
  1394.  
  1395. ; --------------------------------------------------------------
  1396.  
  1397. tint_txurun:
  1398.     pr_ch_al    'd'
  1399.     mov    bx,hdlc0_data.txisr_w_pkt    ;point to the packet buffer
  1400.     call    tint_reset    ;reset pointers etc...
  1401.     ret
  1402.  
  1403.  
  1404. tint_tx419:
  1405. ;
  1406. ; - for MT8952B fifo stuff up to 15 chars at a time
  1407. ;
  1408. ;    NOW NEED TO POINT DX at TX FIFO
  1409. ;
  1410.     mov    dx,board_w_hdlc0        ;make dx point at transmit fifo
  1411.     add    dx,hdlc_bw_transmit
  1412.     mov    cx,15                   ;fifo fill-loop counter
  1413.     mov    bx,hdlc0_data.txisr_w_count    ;get count of bytes left
  1414.     mov    si,hdlc0_data.txisr_w_byte    ;get pointer to next byte
  1415. tint_next:
  1416.     lodsb                ;fetch next char
  1417.     dec    bx            ;reduce count of remaining bytes
  1418.     jne    not_send_last
  1419.     push    dx                ;save dx
  1420.     mov    dx,board_w_hdlc0
  1421.     add    dx,hdlc_b_control
  1422.     push    ax
  1423.     in    al,dx                ;get current hdlc control reg
  1424.     or    al,hdlc_control_eop    ;mark as end of packet
  1425.     out    dx,al                ;and tell the 8952
  1426.     pop    ax                ; restore al
  1427.     pop    dx                ;and dx
  1428.  
  1429. not_send_last:
  1430.     out    dx,al            ;output char
  1431.     or    bx,bx        ;any more chars to output
  1432.     je    tint_no_more        ;none...
  1433.     loop    tint_next        ;loop while fifo not full
  1434. ;
  1435. ;    Still some more so select TXURUN and TX419 ints enabled
  1436. ;
  1437.     pr_ch_al    'e'
  1438.     mov    dx,board_w_hdlc0
  1439.     add    dx,hdlc_bw_intenable
  1440. ;    in    al,dx                ;get current hdlc intenable
  1441.     mov    al,hdlc0_data.copy_intenable
  1442. ;
  1443. ;    switch off txdone interrupt and enable tx419 and txurun
  1444. ;
  1445.     and    al,not hdlc_intenable_txdone
  1446.     or    al,hdlc_intenable_tx419 or hdlc_intenable_txurun
  1447.     out    dx,al                ;and tell the 8952
  1448.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1449.  
  1450.     mov    hdlc0_data.txisr_w_count,bx    ;save count of bytes left
  1451.     mov    hdlc0_data.txisr_w_byte,si    ;save pointer to next byte
  1452.     clc        ;clear carry, all ok
  1453.     ret        ;and exit
  1454.  
  1455. tint_no_more:
  1456. ;
  1457. ;    No more so select TXDONE and TXURUN ints enabled only
  1458. ;
  1459.     pr_ch_al    'f'
  1460.     mov    dx,board_w_hdlc0
  1461.     add    dx,hdlc_bw_intenable
  1462. ;    in    al,dx                ;get current hdlc intenable
  1463.     mov    al,hdlc0_data.copy_intenable
  1464. ;
  1465. ;    switch off tx419 interrupt and enable txurun and txdone 
  1466. ;
  1467.     and    al,not hdlc_intenable_tx419
  1468.     or    al,hdlc_intenable_txdone or hdlc_intenable_txurun
  1469.     out    dx,al                ;and tell the 8952
  1470.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1471.  
  1472.     mov    hdlc0_data.txisr_w_count,bx    ;save count of bytes left
  1473.     mov    hdlc0_data.txisr_w_byte,si    ;save pointer to next byte
  1474.     clc        ;clear carry if all ok
  1475.     ret        ;and exit
  1476.  
  1477. ;No more characters to transmit -- disable transmit interrupts.
  1478.  
  1479. tint_txdone:
  1480. ;    pr_ch_al    'g'
  1481.     mov    bx,hdlc0_data.txisr_w_pkt    ;get pointer to isrs pkt
  1482.     or    bx,bx                ;check if pkt pointer is 0
  1483.     je    tint_skip
  1484.     mov    [bx].buff_w_owner,owner_k_empty;set owned by empty
  1485. tint_skip:
  1486.     call    tint_new    ;try to move to next buffer
  1487.     jc    tint_all_empty    ;if carry set then none left
  1488.     clc
  1489.     ret
  1490.  
  1491. tint_all_empty:
  1492. ;
  1493. ;    No more so set all tx ints off
  1494. ;
  1495. ;    pr_ch_al    'h'
  1496.     mov    dx,board_w_hdlc0
  1497.     add    dx,hdlc_bw_intenable
  1498. ;    in    al,dx                ;get current hdlc intenable
  1499.     mov    al,hdlc0_data.copy_intenable
  1500. ;
  1501. ;    switch off tx419, txurun and txdone 
  1502. ;
  1503.     and    al,not (hdlc_intenable_tx419 or hdlc_intenable_txdone or hdlc_intenable_txurun)
  1504.     out    dx,al                ;and tell the 8952
  1505.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1506.  
  1507.     xor    ax,ax        ;clear ax
  1508.     mov    hdlc0_data.txisr_w_pkt,ax    ;save in pointer to buffer
  1509.     ret
  1510.  
  1511. ;
  1512. ;    Routine to get info for next packet from queue
  1513. ;
  1514. tint_new:
  1515.     mov    bx,hdlc0_data.txq_w_front    ;get pointer to front of queue
  1516.     cmp    [bx].buff_w_owner,owner_k_queue    ;belongs to q?
  1517.     jne    tint_no_buffers_in_queue
  1518. ;
  1519. ;    now bump the front of queue
  1520. ;
  1521.     pr_ch_al    'i'
  1522.     mov    ax,[bx].buff_w_next    ;point to buffer
  1523.     mov    hdlc0_data.txq_w_front,ax    ;adjust front of queue
  1524. ;
  1525.     call    tint_reset    ;and set the pointers etc.
  1526.     ret
  1527.  
  1528. tint_reset:
  1529.     or    bx,bx
  1530.     jz    tint_reset_problem
  1531.     mov    [bx].buff_w_owner,owner_k_isr;set owned by the isr
  1532.     mov    ax,[bx].buff_w_size    ;get size of data unit
  1533.     mov    hdlc0_data.txisr_w_count,ax    ;and save it for us
  1534.     mov    hdlc0_data.txisr_w_pkt,bx    ;save pointer to buffer
  1535.     lea    ax,[bx].buff_info    ;get address of data unit
  1536.     mov    hdlc0_data.txisr_w_byte,ax    ;and save for us
  1537.     call    tint_tx419        ;and pretend we had a tx419
  1538.     ret
  1539. tint_reset_problem:
  1540.     stc
  1541.     ret
  1542. tint_no_buffers_in_queue:
  1543.     pr_ch_al    'j'
  1544.     stc        ;set carry - could not do it
  1545.     ret
  1546.  
  1547. ;Set bit(s) in I/O port
  1548. setbit:
  1549. ;enter with dx = port, ah = bit to set.
  1550.     in    al,dx
  1551.     or    al,ah
  1552.     out    dx,al
  1553.     ret
  1554.  
  1555.  
  1556. ;Clear bit(s) in I/O port
  1557. clrbit:
  1558. ;enter with dx = port, ah = bit to set.
  1559.     in    al,dx
  1560.     not    al            ;perform an and-not using DeMorgan's.
  1561.     or    al,ah
  1562.     not    al
  1563.     out    dx,al
  1564.     ret
  1565.  
  1566. ;
  1567. ;    Now define some buffers for the rings.
  1568. ;    Do it statically now because its easier.
  1569. ;
  1570. ;    First the transmit ring
  1571. ;
  1572. t1_buff    buff    <offset t8_buff, offset t2_buff>
  1573. t2_buff    buff    <offset t1_buff, offset t3_buff>
  1574. t3_buff    buff    <offset t2_buff, offset t4_buff>
  1575. t4_buff    buff    <offset t3_buff, offset t5_buff>
  1576. t5_buff    buff    <offset t4_buff, offset t6_buff>
  1577. t6_buff    buff    <offset t5_buff, offset t7_buff>
  1578. t7_buff    buff    <offset t6_buff, offset t8_buff>
  1579. t8_buff    buff    <offset t7_buff, offset t1_buff>
  1580. ;
  1581. ;    Now the Receive ring
  1582. ;
  1583. r1_buff    buff    <offset r8_buff, offset r2_buff>
  1584. r2_buff    buff    <offset r1_buff, offset r3_buff>
  1585. r3_buff    buff    <offset r2_buff, offset r4_buff>
  1586. r4_buff    buff    <offset r3_buff, offset r5_buff>
  1587. r5_buff    buff    <offset r4_buff, offset r6_buff>
  1588. r6_buff    buff    <offset r5_buff, offset r7_buff>
  1589. r7_buff    buff    <offset r6_buff, offset r8_buff>
  1590. r8_buff    buff    <offset r7_buff, offset r1_buff>
  1591. ;
  1592. ;    include the serial trace output subroutines
  1593. ;
  1594.  
  1595.     include    sersub.asm
  1596.  
  1597. ;any code after this will not be kept after initialization.
  1598. end_resident    label    byte
  1599.  
  1600.     public    usage_msg
  1601. usage_msg    db    "usage: EXPRESS packet_int_no [-n] [driver_class] [int_no] ",CR,LF
  1602.         db    "   -n instructs card to be an NT",CR,LF
  1603.         db    "   The driver_class should be SLIP or a number.",CR,LF,'$'
  1604.  
  1605.     public    copyright_msg
  1606. copyright_msg    db    "Packet driver for MITEL EXPRESS CARD, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  1607.         db    "Portions Copyright 1988 Phil Karn",CR,LF
  1608.         db    "ISDN bits by Dave Price and Bob Gautier",CR,LF,'$'
  1609.  
  1610. class_name_ptr    dw    ?
  1611. class_name    db    "Interface class ",'$'
  1612. slip_name    db    "SLIP",CR,LF,'$'
  1613. int_no_name    db    "Interrupt number ",'$'
  1614. express_start    db    "starting to initial EXPRESS card",CR,LF,'$'
  1615. express_finish    db    "completed initialization of EXPRESS card",CR,LF,'$'
  1616.  
  1617.     extrn    set_recv_isr: near
  1618.  
  1619. ;enter with si -> argument string, di -> word to store.
  1620. ;if there is no number, don't change the number.
  1621.     extrn    get_number: near
  1622.  
  1623. ;enter with dx -> name of word, di -> dword to print.
  1624.     extrn    print_number: near
  1625.  
  1626. ;enter with si -> argument string.
  1627. ;skip spaces and tabs.  Exit with si -> first non-blank char.
  1628.     extrn    skip_blanks: near
  1629.  
  1630.  
  1631.     public    parse_args
  1632. parse_args:
  1633. ;exit with nc if all went well, cy otherwise.
  1634.     call    skip_blanks
  1635.     cmp    al,'-'            ;did they specify a switch?
  1636.     jne    not_switch
  1637. ;
  1638. ;    Only SUPPORT -n SWITCH ARGUMENT AT THE MOMENT
  1639. ;
  1640.     cmp    byte ptr [si+1],'n'    ;did they specify '-n'?
  1641.     je    got_NT_switch
  1642.     stc                ;no, must be an error.
  1643.     ret
  1644. got_NT_switch:
  1645.     mov    NT_switch,1
  1646.     add    si,2            ;skip past the switch's characters.
  1647.     jmp    parse_args        ;go parse more arguments.
  1648. not_switch:
  1649.     or    al,20h            ;convert to lower case (assuming letter).
  1650. parse_args_2:
  1651.     cmp    al,'s'
  1652.     jne    parse_args_3
  1653.     mov    driver_class,6        ;SLIP, from packet spec.
  1654.     mov    dx,offset slip_name
  1655.     jmp    short parse_args_1
  1656. parse_args_3:
  1657.     mov    di,offset driver_class
  1658.     call    get_number
  1659.     mov    class_name_ptr,0
  1660.     jmp    short parse_args_6
  1661. parse_args_1:
  1662.     mov    class_name_ptr,dx
  1663. parse_args_5:
  1664.     mov    al,[si]            ;skip to the next blank or CR.
  1665.     cmp    al,' '
  1666.     je    parse_args_6
  1667.     cmp    al,CR
  1668.     je    parse_args_6
  1669.     inc    si            ;skip the character.
  1670.     jmp    parse_args_5
  1671. parse_args_6:
  1672.     mov    di,offset int_no
  1673.     call    get_number
  1674. ;
  1675. ;    Might get number of buffer in TX queue here.
  1676. ;
  1677.     clc
  1678.     ret
  1679.  
  1680.  
  1681. ; --------------------------------------------------------------
  1682. ;
  1683. ;  etopen
  1684. ;
  1685.  
  1686.     public    etopen
  1687. etopen:
  1688.     pushf
  1689.     cli
  1690.  
  1691.     call    open    ; open the serial port for traces
  1692.  
  1693.     ;let user know we are about to initial
  1694.     ; the express card
  1695.  
  1696.     pr_ch_al    '$'
  1697. ;
  1698. ;Now set up the Mitel Express Card
  1699. ;
  1700. ;
  1701. ;    First the dphone - this controls timing as well
  1702. ;
  1703.     out_chip_reg_value    board_w_dphone,dphone_b_test,dphone_test_disable
  1704. ;
  1705. ;    Now the board timing via the dphone sense/drive port
  1706. ;
  1707.     out_chip_reg_value    board_w_dphone,dphone_b_sddir,dphone_sddir_allout
  1708.     cmp    NT_switch,1    ;has user selected NT operation
  1709.     jne    act_as_te        ;no so set as TE
  1710.     out_chip_reg_value    board_w_dphone,dphone_b_sddata,dphone_sddata_nt
  1711.     jmp    te_nt_set
  1712.  
  1713. act_as_te:
  1714.     out_chip_reg_value    board_w_dphone,dphone_b_sddata,dphone_sddata_te
  1715.  
  1716. te_nt_set:
  1717.  
  1718. ;
  1719. ;    Now set use of st-bus timeslots
  1720. ;
  1721.     out_chip_reg_value    board_w_dphone,dphone_b_time,<dphone_time_c or dphone_time_pcmb1>
  1722. ;
  1723. ;    Now stop the watchdog
  1724. ;
  1725.     out_chip_reg_value    board_w_dphone,dphone_b_wdog,0
  1726. ;
  1727. ;    Now set the tone values
  1728. ;
  1729.     out_chip_reg_value    board_w_dphone,dphone_b_tone1,dphone_tone_697
  1730.     out_chip_reg_value    board_w_dphone,dphone_b_tone2,dphone_tone_1209
  1731. ;
  1732. ;    Now set up the dsp
  1733. ;
  1734.     out_chip_reg_value    board_w_dphone,dphone_b_dsp,<dphone_dsp_cpcmen or dphone_dsp_dpcmen or dphone_dsp_dual>
  1735. ;
  1736. ;    Now set up the transducers
  1737. ;
  1738.     out_chip_reg_value    board_w_dphone,dphone_b_trans,<dphone_trans_side or dphone_trans_hsmic or dphone_trans_hsskr>
  1739. ;
  1740. ;    Finally the Receive gain control
  1741. ;
  1742.     out_chip_reg_value    board_w_dphone,dphone_b_rgain,dphone_rgain_rfg_m7
  1743. ;
  1744. ;    Second the snic
  1745. ;
  1746.     out_chip_reg_value    board_w_snic,snic_b_master,<snic_master_cstenable or snic_master_msdisable or snic_master_irqenable>
  1747.     out_chip_reg_value    board_w_snic,snic_b_stbus,snic_stbus_all
  1748. ;
  1749. ;    Now set up the hdlc controller
  1750. ;
  1751.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,hdlc_time_rst
  1752. ;
  1753. ;    NOTE you are required to clear reset TWICE
  1754. ;
  1755.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,<hdlc_time_ic or hdlc_time_brck or hdlc_time_c2bits8>
  1756.     out_chip_reg_value    board_w_hdlc0,hdlc_b_time,<hdlc_time_ic or hdlc_time_brck or hdlc_time_c2bits8>
  1757.  
  1758.     out_chip_reg_value    board_w_hdlc0,hdlc_b_control,<hdlc_control_rxen or hdlc_control_txen>
  1759.  
  1760.     out_chip_reg_value    board_w_hdlc0,hdlc_b_raddress,00
  1761.     out_chip_reg_value    board_w_hdlc0,hdlc_bw_wdog,00
  1762.  
  1763.     out_chip_reg_value    board_w_hdlc0,hdlc_bw_intenable,<hdlc_intenable_eopd or hdlc_intenable_fa or hdlc_intenable_rx1519 or hdlc_intenable_rxoflw>
  1764.     mov    hdlc0_data.copy_intenable,al        ;and save it
  1765.  
  1766. ;
  1767. ;    Now the DX; plug up the channels and send messages etc,
  1768. ;
  1769.  
  1770.     dx_source    snic_stream,snic_b2_channel,dphone_stream,dphone_b1_channel
  1771.     dx_source    dphone_stream,dphone_b1_channel,snic_stream,snic_b2_channel
  1772.  
  1773.     dx_source    snic_stream,snic_b1_channel,hdlc_stream,hdlc_b1_channel
  1774.     dx_source    hdlc_stream,hdlc_b1_channel,snic_stream,snic_b1_channel
  1775.  
  1776. ;
  1777. ;    MIGHT NEED TO CHANGE THE NEXT FOR NT OPERATION
  1778. ;
  1779.  
  1780.     dx_message    snic_stream,snic_c_channel,<<snic_c_ar or snic_c_clrdia>>
  1781.  
  1782.     ;let user know we have finished
  1783.     ; initializing the express card
  1784.  
  1785.     pr_ch_al    '%'
  1786.  
  1787. ;Set interrupt vector to EXPRESS handler
  1788.  
  1789.     call    set_recv_isr
  1790.  
  1791.     mov    dx,offset end_resident
  1792.  
  1793.     push    dx            ;save the ending address.
  1794.  
  1795.     pop    dx            ;return the ending address.
  1796.     popf
  1797.     clc                ;indicate no errors.
  1798.     ret
  1799.  
  1800.  
  1801.     public    print_parameters
  1802. print_parameters:
  1803.     cmp    class_name_ptr,0
  1804.     je    echo_args_1
  1805.  
  1806.     mov    dx,offset class_name
  1807.     mov    ah,9
  1808.     int    21h
  1809.     mov    dx,class_name_ptr
  1810.     mov    ah,9
  1811.     int    21h
  1812.     jmp    short echo_args_2
  1813. echo_args_1:
  1814.     mov    di,offset driver_class
  1815.     mov    dx,offset class_name
  1816.     call    print_number
  1817. echo_args_2:
  1818.  
  1819.     mov    di,offset int_no
  1820.     mov    dx,offset int_no_name
  1821.     call    print_number
  1822.  
  1823.     ret
  1824.  
  1825. code    ends
  1826.  
  1827.     end
  1828.